///////////////////////////////////////////////////////////////////////////////
////  (c) Chaichuk AU (chaichuk@mail.ru), 								   ////
////  2004, Chelyabinsk, NTC Privodnaya Tehnika (momentum@chel.surnet.ru)  ////
///////////////////////////////////////////////////////////////////////////////

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/dispatch.h>
#include <sys/iofunc.h>
#include <time.h>
#include <sys/netmgr.h>

#include "iofuncs.h"

static	void	optproc (int, char **);
static	void	execute_resmgr (void);

const char*	progname 	= "ctansi";
const char* name 		= "/dev/ctansi";

int   	port_fd 	= -1;
char*	port_name 	= NULL;
int   	port_speed  = 4800;

int
main (int argc, char **argv)
{
	struct sched_param param;

	if (ThreadCtl (_NTO_TCTL_IO, 0) == -1) {
		fprintf (stderr, "%s:  can't obtain I/O privilege; ensure you are running as root! (errno %d (%s))\n", progname, errno, strerror (errno));
		exit (EXIT_FAILURE);
	}

	optproc (argc, argv);

	param.sched_priority = 20;
	sched_setparam (0, &param);

	execute_resmgr ();						// never returns

	return (EXIT_SUCCESS);
}

static void
execute_resmgr (void)
{
	resmgr_attr_t			resmgr_attr;
	resmgr_connect_funcs_t	connect_func;
	resmgr_io_funcs_t		io_func;
	dispatch_t				*dpp;
	resmgr_context_t		*ctp;
	iofunc_attr_t			attr;


	// create the dispatch structure
	if ((dpp = dispatch_create ()) == NULL) {
		perror ("Unable to dispatch_create().");
		exit (EXIT_FAILURE);
	}

	// initialize the various data structures
	memset (&resmgr_attr, 0, sizeof (resmgr_attr));

	// bind default functions into the outcall tables
	iofunc_func_init (_RESMGR_CONNECT_NFUNCS, &connect_func, _RESMGR_IO_NFUNCS, &io_func);
	iofunc_attr_init (&attr, S_IFNAM | 0666, 0, 0);
	
	io_func.devctl 	= io_devctl;

	// establish a name in the pathname space
	if (resmgr_attach (dpp, &resmgr_attr, name, _FTYPE_ANY, 0, &connect_func, &io_func, &attr) == -1) {
		perror ("Unable to resmgr_attach. ");
		exit (EXIT_FAILURE);
	}

	ctp = resmgr_context_alloc (dpp);
	
		
	// wait here forever, handling messages
	while (1) {
		if ((ctp = resmgr_block (ctp)) == NULL) {
			perror ("Unable to resmgr_block(). ");
			exit (EXIT_FAILURE);
		}
		resmgr_handler (ctp);
	}
}

static void
usageError (void)
{
	fprintf (stderr, "%s:  error in use, type \"use %s\" for usage\n", progname, progname);
	exit (1);
}

static void
optproc (int argc, char **argv)
{
	int					opt;

	while ((opt = getopt (argc, argv, "p:b:")) != -1) {
		switch (opt) {
			case 'p': 
				port_name = strdup (optarg);
				break;
			case 'b': 
				port_speed = atoi (optarg);
				break;
	
		default:
			usageError ();
			break;
		}
	}
	if (port_name == NULL) usageError ();
}